<?php

namespace App\Services\WxAutoreply;

use App\Models\WxAutoreply;
use Illuminate\Support\Facades\Cache;

/**
 * 自动回复服务类
 * @package App\Services
 */
class WxAutoreplyService extends \App\Services\WxCommon\WxBase
{
    //回复消息类型常量
    const MSG_TYPE_TEXT = 'text';
    const MSG_TYPE_NEWS = 'news';
    const MSG_TYPE_IMAGE = 'image';
    const MSG_TYPE_VOICE = 'voice';
    const MSG_TYPE_VIDEO = 'video';
    const MSG_TYPE_MUSIC = 'music';

    private $msgTypeList;

    /**
     * 构造函数
     */
    public function __construct($appid = '')
    {
        parent::__construct($appid);

        //消息类别列表
        $this->msgTypeList = [
            self::MSG_TYPE_TEXT => '文本',
            self::MSG_TYPE_NEWS => '图文',
            self::MSG_TYPE_IMAGE => '图片',
            self::MSG_TYPE_VOICE => '语音',
            self::MSG_TYPE_VIDEO => '视频',
            self::MSG_TYPE_MUSIC => '音乐',
        ];
    }

    /**
     * 获取回复类型列表
     * @return array
     */
    public function getMsgTypeList()
    {
        return $this->msgTypeList;
    }

    /**
     * 获取回复消息类型
     * @param $msgType
     * @return mixed|string
     */
    public function getMsgTypeStr($msgType)
    {
        return isset($this->msgTypeList[$msgType]) ? $this->msgTypeList[$msgType] : '';
    }
    /**
     * 保存自动回复数据
     * @param $request
     * @return bool
     * @throws \Exception
     */
    public function save($request)
    {
        \DB::beginTransaction();
        try {
            $id = $request->id ?? 0;
            if ($id) {
                $autoReplyModel = WxAutoreply::where('appid', $this->appid)->findOrFail($id);
            } else {
                $autoReplyModel = new WxAutoreply;
            }
            $autoReplyModel->appid = $this->appid;
            $autoReplyModel->name = $request->name ?? '';
            $autoReplyModel->keywords = $request->keywords ?? [];
            $autoReplyModel->is_open = $request->is_open ?? [];
            $autoReplyModel->start_time = $request->start_time ? strtotime($request->start_time) : null;
            $autoReplyModel->end_time = $request->end_time ? strtotime($request->end_time) : null;
            $autoReplyModel->msg_type = $request->msg_type;
            $autoReplyModel->order_num = (int)$request->order_num;
            $autoReplyModel->content = $request->content ?? '';
            //图文、图片、语音、视频素材
            if (in_array($request->msg_type, ['news', 'image', 'voice', 'video'])) {
                $autoReplyModel->material_id = $request->material['material_id'];
                if (empty($autoReplyModel->material_id)){
                    throw new \Exception('请确保素材上传成功');
                }
            }
            //音乐素材
            if ($request->msg_type == 'music') {
                $musicService = new \App\Services\WxMaterial\WxMaterialMusic();
                $musicData = $musicService->save([
                    'material_id' => $request->material['material_id'] ?? 0,
                    'title' => $request->material['title'] ?? '',
                    'description' => $request->material['description'] ?? '',
                    'thumb_view_url' => $request->material['thumb_view_url'] ?? '',
                    'music_url' => $request->material['music_url'] ?? '',
                    'hq_music_url' => $request->material['hq_music_url'] ?? '',
                ]);
                $autoReplyModel->material_id = $musicData['material_id'] ?? 0;
                if (empty($autoReplyModel->material_id)){
                    throw new \Exception('请确保音乐上传成功');
                }
            }
            $autoReplyModel->save();
            \DB::commit();
        } catch (\Exception $e) {
            \DB::rollBack();
            throw new \Exception($e->getMessage());
        }
        //更新关键字缓存
        $this->getValidCacheAutoReplyList(true);
        return true;
    }

    /**
     * 删除自动回复数据
     * @param $id
     * @return mixed
     */
    public function del($id)
    {
        $findMaterial = WxAutoreply::where('appid', $this->appid)->findOrFail($id);
        return $findMaterial->delete();
    }

    /**
     * 获取缓存中的自动回复列表
     * @param bool $isRefresh
     * @return mixed
     */
    public function getValidCacheAutoReplyList($isRefresh = false)
    {
        $cacheKey = 'wxautoreply_keywords_' . $this->appid;
        //Cache::delete($cacheKey);
        $cacheData = Cache::get($cacheKey);
        if (!$cacheData || $isRefresh){
            $cacheData = WxAutoreply::where('appid', $this->appid)->where('is_open', 1)->orderBy('order_num','asc')->get();
            $cacheData && $cacheData = $cacheData->toArray();
            if ($cacheData){
                Cache::put($cacheKey, $cacheData, 60);
            }
        }
        return $cacheData;
    }

    /**
     * 检查是否命中关键字并获取自动回复内容
     * @param $keyword
     * @return bool|\EasyWeChat\Kernel\Messages\Text
     */
    public function checkHitKeyword($keyword)
    {
        $autoreplyList = $this->getValidCacheAutoReplyList();
        if ($autoreplyList){
            foreach ($autoreplyList as $reply){
                if (in_array($keyword, $reply['keywords'])){
                    switch ($reply['msg_type']){
                        case self::MSG_TYPE_TEXT://文本
                            return new \EasyWeChat\Kernel\Messages\Text($reply['content']);
                            break;
                        case self::MSG_TYPE_NEWS://图文
                        case self::MSG_TYPE_IMAGE://图片
                        case self::MSG_TYPE_VOICE://语音
                        case self::MSG_TYPE_VIDEO://视频
                        case self::MSG_TYPE_MUSIC://音乐
                            return (new \App\Services\WxMaterial\WxMaterialService($this->appid))->createMaterial($reply['msg_type'])->getPassiveReplyData($reply['material_id']);
                            break;
                    }
                }
            }
        }
        return false;
    }
}